package cn.pconline.autoclub.task.data;

import cn.pconline.autoclub.task.AppUtils;
import cn.pconline.autoclub.task.DBUtils;
import cn.pconline.autoclub.task.util.IdGeneratorByTable;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author <a href="mailto:chensy0203@163.com">chensy</a>
 */
public class SyncDynaPraise {

    private static final Logger log = LoggerFactory.getLogger(SyncDynaPraise.class);
    private static IdGeneratorByTable idGenerator = new IdGeneratorByTable();
    //private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
    static List<String> dynaPraiseColumns = null;
    static List<String> userPraiseColumns = null;

    static {
        try {
            dynaPraiseColumns = DBUtils.getColumns("ac_dyna_praise");
            userPraiseColumns = DBUtils.getColumns("ac_user_praise");
        } catch (SQLException e) {
            log.error("get table columns error.", e);
        }
    }

    public static void main(String[] args) {
        AppUtils.initLog(SyncDynaPraise.class);
        String fileName = null;
        if (args != null && args.length > 0) {
            fileName = args[0];
        }
        //fileName = "E:\\work\\autoclub\\branches\\autoclub_4.0_beta\\crontab\\task\\conf\\data.txt";
        if (fileName == null) {
            log.error("the file name must not be null, please input");
            return;
        }
        try {
            log.info("start sync praise");
            int count = handlePraiseData(fileName, new SyncTopic.LineProcess() {
                public int process(String line) {
                    try {
                        JSONObject msg = JSON.parseObject(line);//new JSONObject();
                        log.info("praise: {}", msg);
                        return syncPraise(msg);
                    } catch (RuntimeException ex) {
                        ex.printStackTrace();
                    }
                    return 0;
                }
            });
            log.info("add total: {}", count);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //String text = {"dynaInfoId":123789,"userId":123456,"praiseTime":"2014-11-09 18:28:27","status":1,"isRead":1,"dynaInfoCreateBy":13128876,"dynaInfoCreateAt":"2014-09-23 11:27:36"}{"dynaInfoId":1237889,"userId":1234556,"praiseTime":"2014-11-09 18:29:27","status":2,"isRead":2,"dynaInfoCreateBy":13128877,"dynaInfoCreateAt":"2014-09-23 11:28:36"};
        //JSONObject msg = JSON.parseObject(text);//new JSONObject();
        //syncTopic(msg);
    }

    private static int handlePraiseData(String fileName, SyncTopic.LineProcess callback) throws IOException {
        @SuppressWarnings("resource")
        BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
        String line = null;
        int count = 0;
        while ((line = bufferedReader.readLine()) != null) {
            count += callback.process(line);
        }
        return count;
    }

    static interface LineProcess {

        public int process(String line);
    }

    private static int syncPraise(JSONObject msg) {
        Connection conn = DBUtils.getConnection();
        boolean isAutoCommit = false;
        try {
            isAutoCommit = conn.getAutoCommit();
            conn.setAutoCommit(false);
            Map<String, Object> praiseMap = parseDynaPraise(msg);
            long dynaInfoId = msg.getLongValue("dynainfo_id");
            if (dynaInfoId <= 0) {
                log.info("the dynaInfoId not exists", dynaInfoId);
                return 0;
            }
            long userId = msg.getLongValue("user_id");
            int count = 0;
            if (userId > 0) {
                count = addDynaPraise(conn, praiseMap);
                if (count > 0) {
                    addUserPraise(conn, praiseMap);
                }
                conn.commit();
            }
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (conn != null) {
                try {
                    conn.setAutoCommit(isAutoCommit);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            DBUtils.releaseConn(conn, null, null);
        }
        return 0;
    }

    private static int addDynaPraise(Connection conn, Map<String, Object> praise) throws SQLException {
        String praiseSql = getDynaPraiseSql("ac_dyna_praise_", Long.valueOf((String)praise.get("dynainfo_id")));

        log.debug("add praise\n sql: {}, \n data: {}", praiseSql, praise);
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(praiseSql);
            int idx = 1;
            for (String col : dynaPraiseColumns) {
                ps.setObject(idx++, praise.get(col));
            }
            int count = ps.executeUpdate();
            log.info("add {} dyna praise-{}", count, praise.get("dynainfo_id"));
            return count;
        } finally {
            DBUtils.releaseConn(null, ps, null);
        }
    }

    private static int addUserPraise(Connection conn, Map<String, Object> praise) throws SQLException {
        //topic.put("is_top", 0);
        //top_date
        long userId = (Long) praise.get("user_id");
        String praiseSql = getUserpraiseSql("ac_user_praise_", userId);
        log.debug("add user praise\n sql: {}, \n data: {}", praiseSql, praise);
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(praiseSql);
            int idx = 1;
            for (String col : userPraiseColumns) {
                ps.setObject(idx++, praise.get(col));
            }
            int count = ps.executeUpdate();
            log.info("add {} user praise to user_praise{}-{}", count, praise.get("user_id"), praise.get("dyna_info_id"));
            return count;
        } finally {
            DBUtils.releaseConn(null, ps, null);
        }
    }

    private static String getDynaPraiseSql(String tablePrefix, long x) throws SQLException {
        StringBuilder dynaSqlBuilder = new StringBuilder("INSERT IGNORE INTO ");
        String table = tablePrefix + (x % 10);
        dynaSqlBuilder.append(table);
        //List<String> columns = DBUtils.getColumns(table);
        StringBuilder dynaColumnBuilder = new StringBuilder();
        StringBuilder dynaParamBuilder = new StringBuilder();
        for (String col : dynaPraiseColumns) {
            dynaColumnBuilder.append(',').append(col);
            dynaParamBuilder.append(",?");
        }
        dynaSqlBuilder.append(" (").append(dynaColumnBuilder.substring(1));
        dynaSqlBuilder.append(") values (");
        dynaSqlBuilder.append(dynaParamBuilder.substring(1)).append(")");
        log.debug("dyna insert sql: {}", dynaSqlBuilder);
        return dynaSqlBuilder.toString();
    }

    private static String getUserpraiseSql(String tablePrefix, long x) throws SQLException {
        StringBuilder dynaSqlBuilder = new StringBuilder("INSERT IGNORE INTO ");
        String table = tablePrefix + (x % 10);
        dynaSqlBuilder.append(table);
        //List<String> columns = DBUtils.getColumns(table);
        StringBuilder dynaColumnBuilder = new StringBuilder();
        StringBuilder dynaParamBuilder = new StringBuilder();
        for (String col : userPraiseColumns) {
            dynaColumnBuilder.append(',').append(col);
            dynaParamBuilder.append(",?");
        }
        dynaSqlBuilder.append(" (").append(dynaColumnBuilder.substring(1));
        dynaSqlBuilder.append(") values (");
        dynaSqlBuilder.append(dynaParamBuilder.substring(1)).append(")");
        log.debug("dyna insert sql: {}", dynaSqlBuilder);
        return dynaSqlBuilder.toString();
    }

    /**
     * @param json转topic,只有创建帖子的时候有效
     * @param clubId
     * @return
     */
    private static Map<String, Object> parseDynaPraise(JSONObject msg) {
        Map<String, Object> dyna = new HashMap<String, Object>();
        dyna.put("dynainfo_id", msg.get("dynainfo_id"));
        dyna.put("user_id", Long.valueOf(msg.getString("user_id")));
        dyna.put("praise_time", msg.getDate("praise_time"));
        dyna.put("status", Integer.valueOf(msg.getString("status")));
        dyna.put("is_read", Integer.valueOf(msg.getString("is_read")));
        dyna.put("dynainfo_create_by", Long.valueOf(msg.getString("dynainfo_create_by")));
        dyna.put("dynainfo_create_at", msg.getDate("dynainfo_create_at"));
        return dyna;
    }
}
